package
{
	import com.greensock.TweenLite;
	import flash.utils.setTimeout;
	import tools.events.InteractiveEvent;
	import flash.display.DisplayObjectContainer;
	import com.greensock.easing.Cubic;
	import com.greensock.TweenNano;
	import flash.display.MovieClip;
	import flash.events.Event;
	import tools.timer.CorrectTimerUtil;
	import tools.utils.ArrayUtil;
	import tools.utils.Rnd;
	
	/**
	 * 电梯
	 * @author ase7en
	 */
	public class LiftBox extends MovieClip
	{
		public static const MAX_FLOOR:int = 6;
		public static const MIN_FLOOR:int = 1;
		public static const MAX_PEOPLE:int = 10;
		public static const FLOOR_H:Number = 113;
		private var _currentFloor:int = 1;
		private var _timer:CorrectTimerUtil;
		private var _personArr:Array = [];
		//电梯空位
		private var _seatIndex:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
		//电梯移动方向
		private var _moveType:String = "up";
		//目标层
		private var _endFloor:int;
		//是否有人进入
		private var _isGoIn:Boolean;
		//是否有人离开
		private var _isGoOut:Boolean;
		public function LiftBox()
		{
			_timer = new CorrectTimerUtil(0.5);
			_timer.addEventListener("TIMER", onTimer);
			_timer.addEventListener("TIMER_COMPLETE", onTimerCom);
		}
		
		private function onTimerCom(e:Event):void
		{
		
		}
		
		private function onTimer(e:Event):void
		{
		
		}
		
		public function startMove():void
		{
			_timer.start();
		}
		
		public function stopMove():void
		{
			_timer.stop();
		}
		
		/**
		 * 移动电梯
		 */
		public function move(type:String):void
		{
			if (type != _moveType)
			{
				_moveType = type;
				dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_MOVE_TYPE, _moveType));
			}
			trace("type:" + type);
			trace("移动前：" + this.y);
			
			if (type == "up" && _currentFloor < MAX_FLOOR)
			{
				_currentFloor++;
				trace("向上移动终点：" + (this.y - FLOOR_H));
				TweenLite.to(this, 3, {y: this.y - FLOOR_H, ease: Cubic.easeInOut, onComplete: onMoveCom, onCompleteParams: [_currentFloor]});
			}
			
			else if (type == "down" && _currentFloor > MIN_FLOOR)
			{
				_currentFloor--;
				trace("向下移动终点：" + (this.y + FLOOR_H));
				TweenLite.to(this, 3, {y: this.y + FLOOR_H, ease: Cubic.easeInOut, onComplete: onMoveCom, onCompleteParams: [_currentFloor]});
			}
			trace("移动到的楼层：" + _currentFloor);
		}
		
		/**
		 * 移动完成
		 * @param	currentFloor
		 */
		public function onMoveCom(currentFloor:int):void
		{
			trace("移动后：" + this.y);
			trace("当前楼层：" + _currentFloor);
			dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_CURRENT_FLOOR, _currentFloor));
			//到达指定楼层
			var person:PersonItem;
			var i:int;
			//离开电梯
			checkGoOutLift();
			checkGoInLift();
			checkNextStep();
			//if (_isGoOut) {
				//setTimeout(checkGoInLift, 1000);
			//}else {
				//checkGoInLift();
			//}
			//
			//if (_isGoIn) {
				//setTimeout(checkNextStep, 1000);
			//}else {
				//checkNextStep();
			//}
			
			
			
			
			
			
			
			
			
			trace("----------------onMoveCom------------")
		}
		
		private function checkGoInLift():void
		{
			if (_currentFloor == MAX_FLOOR) {
				_moveType = "down";
				
			}
			if (_currentFloor == MIN_FLOOR) {
				_moveType = "up";
				
			}
			checkLiftMoveMode();
			
			_isGoIn = false;
			//进入电梯
			for (i = 0; i < _personArr.length; i++)
			{
				person = _personArr[i] as PersonItem;
				//当前楼层等待人要去方向和电梯一致的进入电梯
				//判断人的方向
				if (person.fromFloor == _currentFloor)
				{
					trace("进入电梯的人来至：" + person.fromFloor);
					if (person.toFloor > _currentFloor)
					{
						//向上
						if (person.state == "wait" && _moveType == "up")
						{
							//有空位进入
							if (_seatIndex.length > 0)
							{
								trace("电梯向上进入电梯")
								goInLift(_currentFloor, person);
								if (person.toFloor > _endFloor)
								{
									endFloor = person.toFloor;
								}
							}
						}
					}
					else
					{
						//向下
						if (person.state == "wait" && _moveType == "down")
						{
							//有空位进入
							if (_seatIndex.length > 0)
							{
								trace("电梯向下进入电梯")
								goInLift(_currentFloor, person);
								if (person.toFloor < _endFloor)
								{
									endFloor = person.toFloor;
								}
							}
						}
					}
				}
				
			}
		}
		
		private function checkGoOutLift():void
		{
			_isGoOut = false;
			for (i = _personArr.length - 1; i > -1; i--)
			{
				person = _personArr[i] as PersonItem;
				//电梯内部人员在到达指定楼层则出去
				if (person.state == "in" && person.toFloor == _currentFloor)
				{
					trace("离开电梯");
					
					goOutLift(_currentFloor, person);
				}
			}
		}
		
		private function checkNextStep():void 
		{
			var personIn:Boolean;
			//检查判断电梯下一步动作
			for (i = 0; i < _personArr.length; i++)
			{
				
				person = _personArr[i] as PersonItem;
				//电梯有人
				if (person.state == "in")
				{
					trace("电梯有人")
					personIn = true;
					//继续向上
					if (person.toFloor > _currentFloor)
					{
						trace("电梯向上移动")
						move("up");
						return;
					}
					else
					{
						trace("电梯向下移动")
						move("down");
						return;
					}
				}
			}
			
			//电梯没人
			if (!personIn)
			{
				trace("电梯没人")
				if (_moveType == "up")
				{
					trace("电梯向上没人")
					//电梯向上没人
					//响应电梯以上楼层请求
					for (i = 0; i < _personArr.length; i++)
					{
						person = _personArr[i] as PersonItem;
						if (person.state == "wait" && person.fromFloor > currentFloor)
						{
							trace("电梯向上移动")
							move("up");
							return;
						}
					}
					//响应电梯以下楼层请求
					for (i = 0; i < _personArr.length; i++)
					{
						person = _personArr[i] as PersonItem;
						if (person.state == "wait" && person.fromFloor < currentFloor)
						{
							trace("电梯向下移动")
							move("down");
							return;
						}
					}
				}
				else
				{
					//电梯向下没人
					trace("电梯向下没人")
					//响应电梯以下楼层请求
					for (i = 0; i < _personArr.length; i++)
					{
						person = _personArr[i] as PersonItem;
						if (person.state == "wait" && person.fromFloor < currentFloor)
						{
							trace("电梯向下移动")
							move("down");
							return;
						}
					}
					
					//响应电梯以上楼层请求
					for (i = 0; i < _personArr.length; i++)
					{
						person = _personArr[i] as PersonItem;
						if (person.state == "wait" && person.fromFloor > currentFloor)
						{
							trace("电梯向上移动")
							move("up");
							return;
						}
					}
				}
			}
		}
		
		
		
		//判断电梯移动模式
		private function checkLiftMoveMode():void
		{
			
			var person:PersonItem;
			var i:int;
			if (_moveType == "up") {
				var upBoo:Boolean;
				for (i = 0; i < _personArr.length; i++)
				{
					person = _personArr[i] as PersonItem;
					//优先当前楼层人意向
					if (person.fromFloor == _currentFloor&&person.toFloor>_currentFloor) {
						upBoo = true;
						break;
					}
					//当前楼层以上人的意愿
					if (person.fromFloor > _currentFloor && person.toFloor < person.fromFloor) {
						upBoo = true;
						break;
					}
					
				}
				_moveType = (upBoo)?("up"):("down");
			}else {
				for (i = 0; i < _personArr.length; i++)
				{
					person = _personArr[i] as PersonItem;
					if (person.fromFloor == _currentFloor&&person.toFloor< _currentFloor) {
						upBoo = true;
						break;
					}
					if (person.fromFloor < _currentFloor && person.toFloor > person.fromFloor) {
						upBoo = true;
						break;
					}
				}
				_moveType = (upBoo)?("down"):("up");
			}
			
		}
		
		/**
		 * 进入电梯
		 * @param	currentFloor
		 */
		private function goInLift(currentFloor:int, person:PersonItem):void
		{
			_isGoIn = true;
			var randomNum:int = Rnd.integer(0, _seatIndex.length);
			var randomSeat:int = _seatIndex[randomNum];
			ArrayUtil.removeValueFromArray(_seatIndex, randomSeat);
			var liftPerson:LiftPerson = new LiftPerson();
			liftPerson.update(person);
			this["personBox" + randomSeat].addChild(liftPerson);
			person.seat = randomSeat;
			person.state = "in";
			liftPerson.alpha = 0;
			//TweenLite.to(liftPerson, 1, { alpha:1, yoyo:true, repeat:2, onComplete:onGoInLiftCom } );
			TweenLite.to(liftPerson, 1, { alpha:1,onComplete:onGoInLiftCom } );
			dispatchEvent(new InteractiveEvent(LiftEvent.GO_IN_LIFT, person));
		}
		
		private function onGoInLiftCom():void 
		{
			//checkNextStep();
		}
		
		
		
		/**
		 * 离开电梯
		 * @param	currentFloor
		 */
		private function goOutLift(currentFloor:int, person:PersonItem):void
		{
			_isGoOut = true;
			removeLiftPerson(person);
			person.state = "out";
			_seatIndex.push(person.seat);
			_seatIndex.sort(Array.NUMERIC);
			deletePeople(person, currentFloor);
			dispatchEvent(new InteractiveEvent(LiftEvent.GO_OUT_LIFT, person));
		}
		
		private function removeLiftPerson(person:PersonItem):void
		{
			for (var i:int = 1; i <= 10; i++)
			{	
				if (this["personBox" + i].numChildren > 0)
				{
					var liftPerson:LiftPerson = this["personBox" + i].getChildAt(0) as LiftPerson;
					if (liftPerson.fromFloor == person.fromFloor && liftPerson.toFloor == person.toFloor)
					{
						trace("移掉" + "来至：" + liftPerson.fromFloor + "  去：" + liftPerson.toFloor);
						TweenLite.to(liftPerson, 0.25, { alpha:0, yoyo:true, repeat: 4,onComplete:onGoOutLift,onCompleteParams:[liftPerson] } );
						
					}
				}
				
			}
		}
		
		private function onGoOutLift(liftPerson:LiftPerson):void 
		{
			liftPerson.parent.removeChild(liftPerson);
			
		}
		
		/**
		 * 添加人物信息
		 * @param	fromFloor
		 * @param	toFloor
		 */
		public function addPeople(person:PersonItem):void
		{
			_personArr.push(person);
		}
		
		/**
		 * 离开电梯
		 */
		private function deletePeople(person:PersonItem, currentFloor:int):void
		{
			for (var i:int = _personArr.length - 1; i > -1; i--)
			{
				var personItem:PersonItem = _personArr[i] as PersonItem;
				if (personItem.toFloor == currentFloor&&personItem.fromFloor == person.fromFloor)
				{
					_personArr.splice(i, 1);
					break;
				}
			}
		}
		
		public function get seatIndex():Array
		{
			return _seatIndex;
		}
		
		public function set endFloor(value:int):void 
		{
			_endFloor = value;
			dispatchEvent(new InteractiveEvent(LiftEvent.CHANGE_TARGET_FLOOR, endFloor));
		}
		
		public function get endFloor():int 
		{
			return _endFloor;
		}
		
		public function get currentFloor():int 
		{
			return _currentFloor;
		}
	
	}

}